package com.ck.framework.web.service;

import com.ck.common.constant.CacheConstants;
import com.ck.common.entity.SysUser;
import com.ck.common.exception.BusinessException;
import com.ck.common.utils.jwt.RedisCache;
import com.ck.framework.security.threadlocal.AuthenticationContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


/**
 * @author changk
 * @date 2024/8/15 16:10
 * desc:登录密码校验
 */
@Component
@Slf4j
public class SysPasswordService {
    @Autowired
    RedisCache redisCache;

    public void validate(SysUser user) {
        //从ThreadLocal中拿出数据获取用户输入的密码
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
        String username = usernamePasswordAuthenticationToken.getName();
        String password = usernamePasswordAuthenticationToken.getCredentials().toString();

        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
        if (null == retryCount){
            retryCount = 0;
        }
        if (retryCount >= CacheConstants.PASSWORD_MAX_RETRY_COUNT){
            log.info("用户:{} 登录密码错误次数过多,锁定登录",username);
            throw new BusinessException("用户: " + username + " 登录密码错误次数过多,锁定登录");
        }

        if (!matchPassword(password,user.getPassword())){
            retryCount = retryCount + 1;
            log.info("密码错误");
            redisCache.setCacheObject(getCacheKey(username),retryCount,CacheConstants.PASSWORD_LOCK_TIME, TimeUnit.MINUTES);
            throw new BusinessException("密码错误");
        }
        else {
            clearLoginRecordCache(username);
        }
    }
    public void clearLoginRecordCache(String username) {
        if (redisCache.hashKey(getCacheKey(username)))
        {
            redisCache.deleteObject(getCacheKey(username));
        }
    }


    /**
     * 密码校验
     * @param password
     * @param password1
     * @return
     */
    public boolean matchPassword(String password, String password1) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(password, password1);
    }

    /**
     * 登录账户密码错误次数缓存键名
     *
     * @param username 用户名
     * @return 缓存键key
     */
    public String getCacheKey(String username)
    {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }
}
